package com.bkhc.order.service;

import com.alibaba.fastjson.JSONObject;
import com.bkhc.common.constant.OrderStatusConstant;
import com.bkhc.common.entity.User;
import com.bkhc.common.enu.OrderStatusEnum;
import com.bkhc.common.repository.UmcRepository;
import com.bkhc.common.util.CommonUtil;
import com.bkhc.common.util.ExecutorUtils;
import com.bkhc.common.util.MailTemplate;
import com.bkhc.common.util.SendMailJob;
import com.bkhc.common.util.response.PageUtil;
import com.bkhc.common.util.response.ResultCode;
import com.bkhc.common.util.response.ResultJson;
import com.bkhc.common.vo.CustomerVo;
import com.bkhc.common.vo.GoodsSpecVo;
import com.bkhc.common.vo.OrderVo;
import com.bkhc.common.vo.UserBean;
import com.bkhc.order.entity.Order;
import com.bkhc.order.entity.OrderItem;
import com.bkhc.order.repository.BusinessRepository;
import com.bkhc.order.repository.OrderItemRepository;
import com.bkhc.order.repository.OrderRepository;
import com.bkhc.order.repository.ProductRepository;
import com.bkhc.order.utils.DownExcelUtil;
import com.bkhc.order.vo.OrderQuery;
import jdk.nashorn.internal.runtime.logging.Logger;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.*;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderRepository repository;

    @Autowired
    private OrderItemRepository orderItemRepository;

    @Autowired
    private BusinessRepository businessRepository;

    @Autowired
    private UmcRepository umcRepository;

    @Autowired
    private ProductRepository productRepository;


    @Value("${mail.system.to.admins}")
    private String admin;

    @Autowired
    private MailTemplate mailTemplate;

    @Value("${downLoadOrder.downLoadOrderTemplatePath}")
    private String downLoadOrderTemplatePath;

    public ResultJson<?> queryOrders(Order order, int pageIndex, int pageSize) {
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        if(order == null){
            page = repository.findAll(pageRequest);
        }else {
            page = repository.findAll(order, pageRequest);
        }
        //查询订单详细信息封装
        if (page!=null){
            List<Order> orderList = page.getContent();
            orderList.forEach(vo->{
                //TODO 待优化
                List<OrderItem> orderItemList = orderItemRepository.findByOrderCode(vo.getOrderCode());
                vo.setOrderitems(orderItemList);
            });
        }
        PageUtil pageUtil = new PageUtil(page);
        ResultJson<PageUtil> resultJson = ResultJson.success();
        resultJson.setData(pageUtil);
        return  resultJson;
    }

    public ResultJson<List<OrderItem>> queryOrderItem(String orderCode) {
        List<OrderItem> orderItems = orderItemRepository.findByOrderCode(orderCode);
        ResultJson<List<OrderItem>> resultJson = ResultJson.success();
        resultJson.setData(orderItems);
        return  resultJson;
    }

    public ResultJson<?> addOrder(Order order) {
        List<OrderItem> items = order.getOrderitems();
        if(CollectionUtils.isEmpty(items)){
            return ResultJson.failure(ResultCode.NO_ORDER_DATA);
        }
        UserBean user = CommonUtil.getCrruentUser();
        if(user ==null){
            return ResultJson.failure(ResultCode.NO_LOGIN);
        }

        order.setUserId(user.getUserId());
        order.setUsername(user.getUsername());
        order.setCreator(user.getUserId());
        order.setUpdator(user.getUserId());
        //未接入业务系统直接转给产品合伙人
        order.setOrderStatus("2");
        CustomerVo customer = businessRepository.queryCustomer(user.getUserId());
        if(customer==null||StringUtils.isEmpty(customer.getInviteCode())){
            order.setOrderStatus("2");
        }else {
            order.setOrderStatus("1");
            order.setBusinessGroup(customer.getGroupCode());
            order.setBusinessGroupMember(customer.getBusinessGroupMember());
            order.setIdentity(customer.getIdentity());
        }
        order.setBrand(items.get(0).getBrandCode());
        order.setBrandName(items.get(0).getBrandName());
        order.setProductName(items.get(0).getProductName());
        order.setProductName(items.get(0).getProductName());
        repository.save(order);


        for(OrderItem item:items){
            item.setBrandCode(order.getBrand());
            item.setBrandName(order.getBrandName());
            item.setProductName(order.getProductName());
            item.setProductName(order.getProductName());
            item.setOrderCode(order.getOrderCode());
            item.setCreator(user.getUserId());
            item.setUpdator(user.getUserId());
//            Map<String,Double> map=productRepository.queryPrice(item.getInstanceCode(),item.getBrandCode(),item.getPriceVersion());
//            item.setPrice(map.get(order.getIdentity())+"");
            orderItemRepository.save(item);
        }
      //  mailNotice(order);
        return ResultJson.success();
    }

    /**
     * 通知订单处理
     */
    public void mailNotice(Order order){
        if(StringUtils.isEmpty(order.getBusinessGroup())&&StringUtils.isEmpty(order.getBusinessGroupMember())){
            String msg = "用户："+order.getUsername()+"提交订单无法转交";
            String subject = "服务通知：订单无法转交";
            SendMailJob job = new SendMailJob(mailTemplate, msg, admin, subject);
            ExecutorUtils.start(job);
        }
        if(!StringUtils.isEmpty(order.getBusinessGroup())&&StringUtils.isEmpty(order.getBusinessGroupMember())){
            String msg = "用户："+order.getUsername()+"提交订单请处理";
            String subject = "服务通知：订单处理";
            User u = umcRepository.findByUserId(order.getBusinessGroup());
            SendMailJob job = new SendMailJob(mailTemplate, msg, u.getEmail(), subject);
            ExecutorUtils.start(job);
        }
        if(!StringUtils.isEmpty(order.getBusinessGroup())&&!StringUtils.isEmpty(order.getBusinessGroupMember())){
            String msg = "用户："+order.getUsername()+"提交订单请处理";
            String subject = "服务通知：订单处理";
            User u = umcRepository.findByUserId(order.getBusinessGroup());
            SendMailJob job = new SendMailJob(mailTemplate, msg, u.getEmail(), subject);
            ExecutorUtils.start(job);
        }
    }

    public PageUtil getOrdersByproductor(OrderQuery orderQuery, int pageIndex, int pageSize) {
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        //产品合伙人只能看到业务系统提交的订单
        orderQuery.setOrderAuditStatus(OrderStatusConstant.BUSINESS_MANAGER_AGREE);
        page = repository.findAllByOrderQueryByProductor(orderQuery, pageRequest);
        List<Order> orderList = page.getContent();
        if(!CollectionUtils.isEmpty(orderList)){
            List<String> allOrderCode = orderList.stream().map(Order::getOrderCode).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemRepository.findByOrderCodeIn(allOrderCode);
            for(Order order:orderList){
                order.setOrderitems(orderItems.stream().filter(x->x.getOrderCode().equals(order.getOrderCode())).collect(Collectors.toList()));
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        return  pageUtil;
    }

    public ResultJson<?> updateOrderStatusByProductor(String orderCode, String orderStatus) {
        repository.updateOrderStatus(orderCode,orderStatus);
        return ResultJson.success();
    }

    public PageUtil queryOrderByUserId(Order order, int pageIndex, int pageSize) {
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        if(order ==null){
            order = new Order();
        }
        UserBean user = CommonUtil.getCrruentUser();
        if(user == null){
            return null;
        }
        order.setUserId(user.getUserId());
        page = repository.findAll(order, pageRequest);
        List<Order> orderList = page.getContent();
        if(!CollectionUtils.isEmpty(orderList)){
            List<String> allOrderCode = orderList.stream().map(Order::getOrderCode).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemRepository.findByOrderCodeIn(allOrderCode);
            for(Order orderentity:orderList){
                orderentity.setOrderitems(orderItems.stream().filter(x->x.getOrderCode().equals(orderentity.getOrderCode())).collect(Collectors.toList()));
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        return  pageUtil;
    }

    public PageUtil getOrdersByBussiness(Order order, int pageIndex, int pageSize) {
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        if(order == null){
            order = new Order();
        }
        order.setOrderStatus("1");
        page = repository.findAll(order, pageRequest);
        List<Order> orderList = page.getContent();
        if(!CollectionUtils.isEmpty(orderList)){
            List<String> allOrderCode = orderList.stream().map(Order::getOrderCode).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemRepository.findByOrderCodeIn(allOrderCode);
            for(Order tem:orderList){
                tem.setOrderitems(orderItems.stream().filter(x->x.getOrderCode().equals(tem.getOrderCode())).collect(Collectors.toList()));
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        return  pageUtil;
    }

    public ResultJson<?> updateOrderAuditStatus(String orderCode, int auditStatus) {
        repository.updateOrderAuditStatus(orderCode,auditStatus);
        return ResultJson.success();
    }

    public PageUtil queryOrderByPartner(OrderQuery orderQuery, int pageIndex, int pageSize) {
        String jsonstr = (String) CommonUtil.getDataScope();
        Map partner = JSONObject.parseObject(jsonstr, Map.class);
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        //厂商只能看到产品合伙人提交的订单
        orderQuery.setPartnerCode(partner.get("partnerCode").toString());
        orderQuery.setOrderAuditStatus(OrderStatusConstant.PRODUCTOR_AGREE);
        page = repository.findAllByOrderQueryByProductor(orderQuery, pageRequest);
        List<Order> orderList = page.getContent();
        if(!CollectionUtils.isEmpty(orderList)){
            List<String> allOrderCode = orderList.stream().map(Order::getOrderCode).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemRepository.findByOrderCodeIn(allOrderCode);
            for(Order order:orderList){
                order.setOrderitems(orderItems.stream().filter(x->x.getOrderCode().equals(order.getOrderCode())).collect(Collectors.toList()));
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        return  pageUtil;
    }

    public ResultJson<?> assginToPartner(String orderCode) {
        Order order = repository.findByOrderCode(orderCode);
        Map partnerBrand = productRepository.getPartnerByBrandCodeAndProductCode(order.getBrand(), order.getPartnerCode());
        repository.updatePartnerCode(orderCode,1111,partnerBrand.get("partnerCode").toString());
        return ResultJson.success();
    }

    public PageUtil queryOrderByUser(User user, int pageIndex, int pageSize) {
        String jsonstr = (String) CommonUtil.getDataScope();
        Map partner = JSONObject.parseObject(jsonstr, Map.class);
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Order> page = null;
        OrderQuery orderQuery = new OrderQuery();
        orderQuery.setUserId(user.getUserId());
        page = repository.queryOrderByUser(orderQuery, pageRequest);
        List<Order> orderList = page.getContent();
        if(!CollectionUtils.isEmpty(orderList)){
            List<String> allOrderCode = orderList.stream().map(Order::getOrderCode).collect(Collectors.toList());
            List<OrderItem> orderItems = orderItemRepository.findByOrderCodeIn(allOrderCode);
            for(Order order:orderList){
                order.setOrderitems(orderItems.stream().filter(x->x.getOrderCode().equals(order.getOrderCode())).collect(Collectors.toList()));
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        return  pageUtil;
    }

    public void downloadOrder(Order order, HttpServletResponse response){
        UserBean user = CommonUtil.getCrruentUser();
        if(user != null){
            List<OrderItem> ois = orderItemRepository.findByOrderCode(order.getOrderCode());
            List<String> goodsCodeIn = new ArrayList<>();
            ois.forEach((k)->{
                goodsCodeIn.add(k.getGoodsCode());
            });
            List<GoodsSpecVo> list = productRepository.getGoodsSpecbyGoodsCode(goodsCodeIn);
            if(list == null){
                log.info("spec 为空 不做下载处理（等待后续更新）");
                return;
            }
            DownExcelUtil.newInstance(downLoadOrderTemplatePath).downLoadExcel(ois,list,response);
        }
    }
}
